package com.company.project.controller;

import com.company.project.core.Result;
import com.company.project.core.ResultGenerator;
import com.company.project.exception.ServiceException;
import com.company.project.model.User;
import com.company.project.service.UserService;
import com.company.project.util.EncryptUtil;
import com.company.project.util.JWTUtil;
import com.company.project.util.RedisUtils;
import com.company.project.util.StringUtil;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/**
 * UserDealController
 *
 * @blame Android Team
 */ /*
 * @Description:    处理注册，登录，修改密码，手机号等常规的用户操作
 * @Author:         brilliantzhao
 * @CreateDate:     2019/5/27 15:55
 * @UpdateUser:
 * @UpdateDate:     2019/5/27 15:55
 * @UpdateRemark:
 */
@RestController
@RequestMapping("")
@Api(value = "User常规操作", tags = "User常规操作接口测试")
@Service("redisTokenManager")
public class UserDealController {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Resource
    private UserService userService;

    // token有效期
    @Value("${spring.redis.expire}")
    private Integer expire;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private UserController userController;

    @PostMapping("/regist")
    @ApiOperation(value = "用户注册", notes = "新用户注册", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user", value = "用户注册的user实例", paramType = "body", dataType = "User", required = true)
    })
    public Result regist(@RequestBody User user) {
        String userPhone = user.getUserPhone();
        String userPwd = user.getPassword();
        // 新用户注册，手机号和密码必须有,必须满足对应的正则
        if (StringUtil.isEmptyOrNull(userPhone) || StringUtil.isEmptyOrNull(userPwd)) {
            throw new ServiceException("手机号码或密码不能为空");
        } else if (userPhone.length() != 11) {
            throw new ServiceException("请输入正确的手机号码");
        } else {
            String checkSql = "SELECT COUNT(id) FROM `user` WHERE user_phone=?";
            int checkSqlInt = jdbcTemplate.queryForObject(checkSql, new Object[]{userPhone}, Integer.class);
            if (checkSqlInt == 0) {
                // 用户名未使用
                // 密码加密处理
                user.setPassword(EncryptUtil.passwordToHash(userPwd));
                userService.save(user);
                return getLoginUser(userPhone, userPwd);
            } else {
                // 用户名已被使用
                throw new ServiceException("该手机号码已注册");
            }
        }
    }

    @PostMapping("/login")
    @ApiOperation(value = "用户登录", notes = "用户登录", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user_phone", value = "用户手机号", paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "password", value = "用户密码", paramType = "query", required = true, dataType = "String"),
    })
    public Result login(@RequestParam String user_phone, @RequestParam String password) {
        // 新用户注册，手机号和密码必须有,必须满足对应的正则
        if (StringUtil.isEmptyOrNull(user_phone) || StringUtil.isEmptyOrNull(password)) {
            throw new ServiceException("手机号码或密码不能为空");
        } else if (user_phone.length() != 11) {
            throw new ServiceException("请输入正确的手机号码");
        } else {
            String encryptedPwd = EncryptUtil.passwordToHash(password);
            String checkSql = "SELECT COUNT(id) FROM `user` WHERE user_phone=? AND password=?";
            int checkSqlInt = jdbcTemplate.queryForObject(checkSql, new Object[]{user_phone, encryptedPwd}, Integer.class);
            if (checkSqlInt == 0) {
                // 不存在该用户
                throw new ServiceException("用户名或密码错误");
            } else {
                // 查找到该用户
                return getLoginUser(user_phone, password);
            }
        }
    }

    /*
     * @Description: 获取登录用户
     * @Author: brilliantzhao
     * @CreateDate: 2019/5/31 13:54
     * @Param:
     * @Return:
     */
    private Result getLoginUser(String user_phone, String password) {
        String getSql = "SELECT id,user_phone,user_name,user_portrait,user_intro,user_gender,user_add,user_comm,user_roomnum,user_labels FROM user WHERE user_phone=?";
        User getSqlUser = (User) jdbcTemplate.queryForObject(getSql, new Object[]{user_phone}, new BeanPropertyRowMapper(User.class));
        // 自动登录，并返回token
        String token = getToken(getSqlUser, password);
        getSqlUser.setToken(token);
        return ResultGenerator.genSuccessResult(getSqlUser);
    }

    /*
     * @Description: 刷新用户token
     * @Author: brilliantzhao
     * @CreateDate: 2019/5/31 17:30
     * @Param:
     * @Return:
     */
    public void refreshUserToken(String token) {
        Object userInfo = redisUtils.get(token);
        if (userInfo != null) {
            redisUtils.set(token, userInfo, expire);
        }
    }

    @PostMapping("/logout")
    @ApiOperation(value = "用户退出登录", notes = "用户退出登录", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user", value = "用户的user实例", paramType = "body", dataType = "User", required = true)
    })
    public Result logout(@RequestBody User user) {
        Integer userId = user.getId();
        String userToken = user.getToken();
        userController.checkNotNull(userId);
        redisUtils.del(userToken);
        return ResultGenerator.genSuccessResult();
    }

    /*
     * @Description: 获取token,根据用户的Id和密码获取
     * @Author: brilliantzhao
     * @CreateDate: 2019/5/29 16:59
     * @Param:
     * @Return:
     */
    private String getToken(User user, String password) {
        JWTUtil jwtUtil = new JWTUtil();
        String token = jwtUtil.createTokenWithClaim(user, password);
        redisUtils.set(token, user, expire);
        return token;
    }

    /*
     * @Description: 根据token获取用户信息
     * @Author: brilliantzhao
     * @CreateDate: 2019/5/31 17:24
     * @Param: [token]
     * @Return: com.company.project.model.User
     */
    public User getUserInfoByToken(String token) {
        Object userInfo = redisUtils.get(token);
        if (userInfo != null) {
            return (User) userInfo;
        }
        return null;
    }

}
